﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Globalization;
using System.Linq.Expressions;
using System.Web.Routing;
using System.Collections;
using System.ComponentModel;
using System.Web.UI.WebControls;
using System.Web.Caching;

namespace Tencent.OA.ACM.App
{
    public static class ControlExtensions
    {
        public static MvcHtmlString MvcMenu(this HtmlHelper htmlHelper, string cssClass, string currentMenuCssClass)
        {
            var CacheMenu = System.Web.HttpContext.Current.Cache;
            int staffID = BancheStaff.CurrentStaffID;
            object menuStr = CacheMenu[staffID.ToString()];
            if (menuStr == null)
            {
                menuStr = Tencent.OA.App.MvcSiteMapExtensions.Menu(htmlHelper, cssClass, currentMenuCssClass);
                CacheMenu.Add(staffID.ToString(), menuStr, null, DateTime.Now.AddMinutes(20), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
            }
            return menuStr == null ? MvcHtmlString.Empty : (menuStr as MvcHtmlString);
        }

        #region TofDeptChooser

        /// <summary>
        /// 选择全体员工的控件。
        /// </summary>
        /// <param name="html">HtmlHelper</param>
        /// <param name="name">用于控件的id和name属性。</param>
        /// <param name="value">控件的值。</param>
        /// <returns></returns>
        public static MvcHtmlString TofDeptChooser(this HtmlHelper html, string name, object value)
        {
            return TofDeptChooser(html, name, value, false);
        }

        /// <summary>
        /// 选择全体员工的控件。
        /// </summary>
        /// <param name="html">HtmlHelper</param>
        /// <param name="name">用于控件的id和name属性。</param>
        /// <param name="value">控件的值。</param>
        /// <param name="multiple">true指示可多选，否则只能选一个。</param>
        /// <returns></returns>
        public static MvcHtmlString TofDeptChooser(this HtmlHelper html, string name, object value, bool multiple)
        {
            return TofDeptChooser(html, name, value, multiple, null);
        }

        /// <summary>
        /// 选择全体员工的控件。
        /// </summary>
        /// <param name="html">HtmlHelper</param>
        /// <param name="name">用于控件的id和name属性。</param>
        /// <param name="value">控件的值。</param>
        /// <param name="multiple">true指示可多选，否则只能选一个。</param>
        /// <param name="callback">选中员工后执行的回调函数，传入的参数是callback(event, data, formatter)。</param>
        /// <returns></returns>
        public static MvcHtmlString TofDeptChooser(this HtmlHelper html, string name, object value, bool multiple, string callback)
        {
            return ChooserInput(html, name, value, multiple, callback, "deptchooser");
        }

        /// <summary>
        /// 选择全体员工的控件。
        /// </summary>
        /// <typeparam name="TModel">实体模型的类型。</typeparam>
        /// <typeparam name="TProperty">员工名称的实体属性类型。</typeparam>
        /// <param name="htmlHelper">HtmlHelper</param>
        /// <param name="expression">员工名称的实体属性表达式。</param>
        /// <returns></returns>
        public static MvcHtmlString TofDeptChooserFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
        {
            return TofDeptChooserFor(htmlHelper, expression, false);
        }

        /// <summary>
        /// 选择全体员工的控件。
        /// </summary>
        /// <typeparam name="TModel">实体模型的类型。</typeparam>
        /// <typeparam name="TProperty">员工名称的实体属性类型。</typeparam>
        /// <param name="htmlHelper">HtmlHelper</param>
        /// <param name="expression">员工名称的实体属性表达式。</param>
        /// <param name="multiple">true指示可多选，否则只能选一个。</param>
        /// <returns></returns>
        public static MvcHtmlString TofDeptChooserFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, bool multiple)
        {
            return TofDeptChooserFor(htmlHelper, expression, multiple, null);
        }

        /// <summary>
        /// 选择全体员工的控件。
        /// </summary>
        /// <typeparam name="TModel">实体模型的类型。</typeparam>
        /// <typeparam name="TProperty">员工名称的实体属性类型。</typeparam>
        /// <param name="htmlHelper">HtmlHelper</param>
        /// <param name="expression">员工名称的实体属性表达式。</param>
        /// <param name="multiple">true指示可多选，否则只能选一个。</param>
        /// <param name="callback">选中员工后执行的回调函数，传入的参数是callback(event, data, formatter)。</param>
        /// <returns></returns>
        public static MvcHtmlString TofDeptChooserFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, bool multiple, string callback)
        {
            return TofDeptChooserFor(htmlHelper, expression, multiple, callback, null);
        }

        /// <summary>
        /// 选择全体员工的控件。
        /// </summary>
        /// <typeparam name="TModel">实体模型的类型。</typeparam>
        /// <typeparam name="TProperty">员工名称的实体属性类型。</typeparam>
        /// <param name="htmlHelper">HtmlHelper</param>
        /// <param name="expression">员工名称的实体属性表达式。</param>
        /// <param name="multiple">true指示可多选，否则只能选一个。</param>
        /// <param name="callback">选中员工后执行的回调函数，传入的参数是callback(event, data, formatter)。</param>
        /// <param name="htmlAttributes">html属性集合。</param>
        /// <returns></returns>
        public static MvcHtmlString TofDeptChooserFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, bool multiple, string callback, object htmlAttributes)
        {
            return ChooserInput<TModel, TProperty>(htmlHelper, expression, multiple, callback, htmlAttributes, "deptchooser");
        }

        #endregion

        #region TofUserChooser

        /// <summary>
        /// 选择全体员工的控件。
        /// </summary>
        /// <param name="html">HtmlHelper</param>
        /// <param name="name">用于控件的id和name属性。</param>
        /// <param name="value">控件的值。</param>
        /// <returns></returns>
        public static MvcHtmlString TofUserChooser(this HtmlHelper html, string name, object value)
        {
            return TofUserChooser(html, name, value, false);
        }

        /// <summary>
        /// 选择全体员工的控件。
        /// </summary>
        /// <param name="html">HtmlHelper</param>
        /// <param name="name">用于控件的id和name属性。</param>
        /// <param name="value">控件的值。</param>
        /// <param name="multiple">true指示可多选，否则只能选一个。</param>
        /// <returns></returns>
        public static MvcHtmlString TofUserChooser(this HtmlHelper html, string name, object value, bool multiple)
        {
            return TofUserChooser(html, name, value, multiple, null);
        }

        /// <summary>
        /// 选择全体员工的控件。
        /// </summary>
        /// <param name="html">HtmlHelper</param>
        /// <param name="name">用于控件的id和name属性。</param>
        /// <param name="value">控件的值。</param>
        /// <param name="multiple">true指示可多选，否则只能选一个。</param>
        /// <param name="callback">选中员工后执行的回调函数，传入的参数是callback(event, data, formatter)。</param>
        /// <returns></returns>
        public static MvcHtmlString TofUserChooser(this HtmlHelper html, string name, object value, bool multiple, string callback)
        {
            return ChooserInput(html, name, value, multiple, callback, "staffChooser");
        }

        /// <summary>
        /// 选择全体员工的控件。
        /// </summary>
        /// <typeparam name="TModel">实体模型的类型。</typeparam>
        /// <typeparam name="TProperty">员工名称的实体属性类型。</typeparam>
        /// <param name="htmlHelper">HtmlHelper</param>
        /// <param name="expression">员工名称的实体属性表达式。</param>
        /// <returns></returns>
        public static MvcHtmlString TofUserChooserFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
        {
            return TofUserChooserFor(htmlHelper, expression, false);
        }

        /// <summary>
        /// 选择全体员工的控件。
        /// </summary>
        /// <typeparam name="TModel">实体模型的类型。</typeparam>
        /// <typeparam name="TProperty">员工名称的实体属性类型。</typeparam>
        /// <param name="htmlHelper">HtmlHelper</param>
        /// <param name="expression">员工名称的实体属性表达式。</param>
        /// <param name="multiple">true指示可多选，否则只能选一个。</param>
        /// <returns></returns>
        public static MvcHtmlString TofUserChooserFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, bool multiple)
        {
            return TofUserChooserFor(htmlHelper, expression, multiple, null);
        }

        /// <summary>
        /// 选择全体员工的控件。
        /// </summary>
        /// <typeparam name="TModel">实体模型的类型。</typeparam>
        /// <typeparam name="TProperty">员工名称的实体属性类型。</typeparam>
        /// <param name="htmlHelper">HtmlHelper</param>
        /// <param name="expression">员工名称的实体属性表达式。</param>
        /// <param name="multiple">true指示可多选，否则只能选一个。</param>
        /// <param name="callback">选中员工后执行的回调函数，传入的参数是callback(event, data, formatter)。</param>
        /// <returns></returns>
        public static MvcHtmlString TofUserChooserFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, bool multiple, string callback)
        {
            return TofUserChooserFor(htmlHelper, expression, multiple, callback, null);
        }

        /// <summary>
        /// 选择全体员工的控件。
        /// </summary>
        /// <typeparam name="TModel">实体模型的类型。</typeparam>
        /// <typeparam name="TProperty">员工名称的实体属性类型。</typeparam>
        /// <param name="htmlHelper">HtmlHelper</param>
        /// <param name="expression">员工名称的实体属性表达式。</param>
        /// <param name="multiple">true指示可多选，否则只能选一个。</param>
        /// <param name="callback">选中员工后执行的回调函数，传入的参数是callback(event, data, formatter)。</param>
        /// <param name="htmlAttributes">html属性集合。</param>
        /// <returns></returns>
        public static MvcHtmlString TofUserChooserFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, bool multiple, string callback, object htmlAttributes)
        {
            return ChooserInput<TModel, TProperty>(htmlHelper, expression, multiple, callback, htmlAttributes, "staffChooser");
        }

        #endregion

        #region 选择用户、工程师,部门的控件

        /// <summary>
        /// 选择用户、工程师的控件
        /// </summary>
        /// <param name="html">HtmlHelper</param>
        /// <param name="name">用于控件的id和name属性。</param>
        /// <param name="value">控件的值。</param>
        /// <param name="multiple">true指示可多选，否则只能选一个。</param>
        /// <param name="callback">选中员工后执行的回调函数，传入的参数是callback(event, data, formatter)。</param>
        /// <param name="chooserType">选择的类型，有staffChooser、engineerChooser</param>
        /// <returns></returns>
        private static MvcHtmlString ChooserInput(this HtmlHelper html, string name, object value, bool multiple, string callback, string chooserType)
        {
            StringBuilder s = new StringBuilder();
            // 首先生成文本框
            var attr = new RouteValueDictionary(new
            {
                @class = chooserType,
                ismultiple = multiple.ToString().ToLowerInvariant()
            });
            if (!string.IsNullOrEmpty(callback))
                attr.Add("callback", callback);
            s.Append(html.TextBox(name, value, attr).ToString());
            return MvcHtmlString.Create(s.ToString());
        }

        private static MvcHtmlString ChooserInput<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, bool multiple, string callback, object htmlAttributes, string chooserType)
        {
            StringBuilder s = new StringBuilder();
            // 首先生成文本框
            var attr = new RouteValueDictionary(new
            {
                @class = chooserType,
                ismultiple = multiple.ToString().ToLowerInvariant()
            });
            if (!string.IsNullOrEmpty(callback))
                attr.Add("callback", callback);
            s.Append(htmlHelper.TextBoxFor(expression, attr).ToString());

            return MvcHtmlString.Create(s.ToString());
        }




        #endregion

        public static MvcHtmlString HomeLinkTab(this HtmlHelper htmlHelper)
        {
            UrlHelper urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
            string[] tabItemTextArr = { "所有路线", "本系统路线", "已成团", "已报名" };
            string[] tabItemHrefArr = { urlHelper.Action("LineList", "Home"), urlHelper.Action("Internal", "Home"), urlHelper.Action("Grouped", "Home"), urlHelper.Action("MyApplicant", "Home") };
            string currentUrl = htmlHelper.ViewContext.HttpContext.Request.FilePath;
            int index = tabItemHrefArr.ToList().IndexOf(currentUrl);

            return LinkTab(
                htmlHelper,
                new object[] {
                    new { text = tabItemTextArr[0], href = tabItemHrefArr[0] },
                    //new { text = tabItemTextArr[1], href = tabItemHrefArr[1] },
                    new { text = tabItemTextArr[2], href = tabItemHrefArr[2] },
                    new { text = tabItemTextArr[3], href = tabItemHrefArr[3] },
                },
                ((index >= 0 && index < 4) ? tabItemTextArr[index] : "")
            );
        }

        // 带连接的标签Tab
        public static MvcHtmlString LinkTab(this HtmlHelper htmlHelper, IEnumerable source, string currentTabName)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            StringBuilder html = new StringBuilder();
            foreach (var item in source)
            {
                string href = null;
                string text = null;
                foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(item))
                {
                    if (string.Equals(descriptor.Name, "href", StringComparison.InvariantCultureIgnoreCase))
                        href = Convert.ToString(descriptor.GetValue(item), CultureInfo.InvariantCulture);

                    if (string.Equals(descriptor.Name, "text", StringComparison.InvariantCultureIgnoreCase))
                        text = Convert.ToString(descriptor.GetValue(item), CultureInfo.InvariantCulture);
                }
                if (!string.IsNullOrEmpty(text))
                {
                    string currTabClass = string.Equals(currentTabName, text, StringComparison.InvariantCultureIgnoreCase) ? " class=\"mod_tabs_current\"" : "";
                    if (!string.IsNullOrEmpty(href))
                        html.AppendFormat("<li{0}><a href=\"{1}\">{2}</a></li>", currTabClass, href, text);
                    else
                        html.AppendFormat("<li{0}>{2}</li>", currTabClass, href, text);
                }
            }
            if (html.Length > 0)
            {
                html.Insert(0, "<ul class=\"linktab\">");
                html.Append("</ul>");
                return MvcHtmlString.Create(html.ToString());
            }
            return MvcHtmlString.Empty;
        }
        #region FckEditor

        /// <summary>
        /// 生成一个FCKEditor文本编辑器。
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="id"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static MvcHtmlString FckEditor(this HtmlHelper htmlHelper, string id, string value)
        {
            return FckEditor(htmlHelper, id, value, 550, 300);
        }
        public static MvcHtmlString FckEditor(this HtmlHelper htmlHelper, string id, string value, Unit width, Unit height)
        {
            StringBuilder s = new StringBuilder();
            UrlHelper url = new UrlHelper(htmlHelper.ViewContext.RequestContext);
            /*s.Append(htmlHelper.Hidden(id, value).ToString());
             s.Append(htmlHelper.Hidden(id + "___Config", "HtmlEncodeOutput=true").ToString());
             s.Append("<iframe id=\"" + id + "___Frame\" src=\"");
             s.Append(UrlHelper.GenerateContentUrl("~/Content/FCKeditor/editor/fckeditor.html", htmlHelper.ViewContext.HttpContext));
             s.Append("?InstanceName=" + id + "\" width=\"600px\" height=\"300px\" frameborder=\"no\" scrolling=\"no\"></iframe>");*/

            s.Append(htmlHelper.TextArea(id, value, new { style = "width:" + width.ToString() + "; height:" + height.ToString() + ";" }).ToString());
            s.Append("<script type=\"text/javascript\" src=\"");
            s.Append(url.Content("~/content/fckeditor/fckeditor.js"));
            s.AppendLine("\"></script><script type=\"text/javascript\">");
            s.AppendLine(string.Format("  var fckEditor = new FCKeditor('{0}', '{1}', '{2}');",
                id,                 // instanceName
                width.ToString(),   // width
                height.ToString()  // height
            ));
            s.AppendLine("  fckEditor.BasePath = '" + url.Content("~/content/fckeditor/") + "';");
            s.AppendLine("  fckEditor.ReplaceTextarea();");
            s.AppendLine("</script>");

            return MvcHtmlString.Create(s.ToString());
        }

        public static MvcHtmlString FckEditor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
        {
            return FckEditor(htmlHelper, expression, 550, 300);
        }
        public static MvcHtmlString FckEditor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Unit width, Unit height)
        {
            StringBuilder s = new StringBuilder();
            UrlHelper url = new UrlHelper(htmlHelper.ViewContext.RequestContext);
            s.Append(htmlHelper.TextAreaFor(expression, new { style = "width:" + width.ToString() + "; height:" + height.ToString() + ";" }).ToString());
            s.Append("<script type=\"text/javascript\" src=\"");
            s.Append(url.Content("~/content/fckeditor/fckeditor.js"));
            s.AppendLine("\"></script><script type=\"text/javascript\">");
            s.AppendLine(string.Format("  var fckEditor = new FCKeditor('{0}', '{1}', '{2}');",
                ExpressionHelper.GetExpressionText(expression), // instanceName
                width.ToString(), // width
                height.ToString() // height
            ));
            s.AppendLine("  fckEditor.BasePath = '" + url.Content("~/content/fckeditor/") + "';");
            s.AppendLine("  fckEditor.ReplaceTextarea();");
            s.AppendLine("</script>");

            return MvcHtmlString.Create(s.ToString());
        }

        #endregion

        /// <summary>
        /// 格式化日期（不带时间）
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static MvcHtmlString FormatDate(this HtmlHelper htmlHelper, DateTime value)
        {
            return FormatDateTimeString(htmlHelper, value, "yyyy-MM-dd");
        }
        /// <summary>
        /// 格式化日期（不带时间）,为null时返回空字符串。
        /// </summary>
        public static MvcHtmlString FormatDate(this HtmlHelper htmlHelper, DateTime? value)
        {
            return FormatDate(htmlHelper, value, "");
        }
        /// <summary>
        /// 格式化日期（不带时间），为null时返回<paramref name="defaultText"/>
        /// </summary>
        /// <param name="defaultText">当<paramref name="value"/>为空时返回该值。</param>
        public static MvcHtmlString FormatDate(this HtmlHelper htmlHelper, DateTime? value, string defaultText)
        {
            if (!value.HasValue)
                return MvcHtmlString.Create(defaultText);
            return FormatDateTimeString(htmlHelper, value.Value, "yyyy-MM-dd");
        }

        //public static MvcHtmlString FormatDate<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string defaultText)
        //{
        //    if (expression == null)
        //        throw new ArgumentNullException("expression");

        //    if (expression.Type == typeof(System.DateTime))
        //    {

        //    }
        //    return MvcHtmlString.Create(defaultText);
        //}

        /// <summary>
        /// 格式化日期时间
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static MvcHtmlString FormatDateTime(this HtmlHelper htmlHelper, DateTime value)
        {
            return FormatDateTimeString(htmlHelper, value, "yyyy-MM-dd HH:mm:ss");
        }
        /// <summary>
        /// 格式化日期时间,为null时返回空字符串。
        /// </summary>
        public static MvcHtmlString FormatDateTime(this HtmlHelper htmlHelper, DateTime? value)
        {
            return FormatDateTime(htmlHelper, value, "");
        }
        /// <summary>
        /// 格式化日期时间，为null时返回<paramref name="defaultText"/>
        /// </summary>
        /// <param name="defaultText">当<paramref name="value"/>为空时返回该值。</param>
        public static MvcHtmlString FormatDateTime(this HtmlHelper htmlHelper, DateTime? value, string defaultText)
        {
            if (!value.HasValue)
                return MvcHtmlString.Create(defaultText);
            return FormatDateTimeString(htmlHelper, value.Value, "yyyy-MM-dd HH:mm:ss");
        }
        private static MvcHtmlString FormatDateTimeString(HtmlHelper htmlHelper, DateTime value, string formatString)
        {
            return MvcHtmlString.Create(value.ToString(formatString, CultureInfo.CurrentCulture));
        }

        public static MvcHtmlString FormatCharge(this HtmlHelper htmlHelper, decimal? charge)
        {
            return MvcHtmlString.Create((charge.HasValue && charge.Value > 0m) ? (charge.Value.ToString("c") + " /人") : "免费");
        }
        public static MvcHtmlString FormatChargeFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
        {
            //if (expression == null)
            //    throw new ArgumentNullException("expression");

            //if (expression.Type == typeof(decimal?))
            //{
            //    var value = ExpressionHelper.GetExpressionText(expression);
            //    return MvcHtmlString.Create(charge.HasValue ? (charge.Value.ToString("c") + "/人") : "免费");
            //}
            return MvcHtmlString.Create("--");
        }

        public static MvcHtmlString DatePicker(this HtmlHelper htmlHelper, string name, DateTime value)
        {
            return htmlHelper.DatePicker(name, value, new { @class = "dateinput" });
        }
        public static MvcHtmlString DatePicker(this HtmlHelper htmlHelper, string name, DateTime value, object htmlAttributes)
        {
            return htmlHelper.DatePicker(name, value, new RouteValueDictionary(htmlAttributes));
        }
        public static MvcHtmlString DatePicker(this HtmlHelper htmlHelper, string name, DateTime value, IDictionary<string, object> htmlAttributes)
        {
            return DatePickerHelper(htmlHelper, name, value, htmlAttributes);
        }
        public static MvcHtmlString DatePicker(this HtmlHelper htmlHelper, string name, DateTime? value)
        {
            return htmlHelper.DatePicker(name, value, new { @class = "dateinput" });
        }
        public static MvcHtmlString DatePicker(this HtmlHelper htmlHelper, string name, DateTime? value, object htmlAttributes)
        {
            return htmlHelper.DatePicker(name, value, new RouteValueDictionary(htmlAttributes));
        }
        public static MvcHtmlString DatePicker(this HtmlHelper htmlHelper, string name, DateTime? value, IDictionary<string, object> htmlAttributes)
        {
            return DatePickerHelper(htmlHelper, name, value.Value, htmlAttributes);
        }

        public static MvcHtmlString DatePickerFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, DateTime>> expression)
        {
            return htmlHelper.DatePickerFor(expression, new { @class = "dateinput" });
        }

        public static MvcHtmlString DatePickerFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, DateTime>> expression, object htmlAttributes)
        {
            return htmlHelper.DatePickerFor(expression, new RouteValueDictionary(htmlAttributes));
        }

        public static MvcHtmlString DatePickerFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, DateTime>> expression, IDictionary<string, object> htmlAttributes)
        {
            var modelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
            DateTime? dt_value = null;
            if (modelMetadata != null && modelMetadata.ModelType == typeof(DateTime) && modelMetadata.Model != null)
            {
                dt_value = Convert.ToDateTime(modelMetadata.Model);
            }
            return DatePickerHelper(htmlHelper, ExpressionHelper.GetExpressionText(expression), dt_value, htmlAttributes);
        }

        public static MvcHtmlString DatePickerFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, DateTime?>> expression)
        {
            return htmlHelper.DatePickerFor(expression, new { @class = "dateinput" });
        }

        public static MvcHtmlString DatePickerFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, DateTime?>> expression, object htmlAttributes)
        {
            return htmlHelper.DatePickerFor(expression, new RouteValueDictionary(htmlAttributes));
        }

        public static MvcHtmlString DatePickerFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, DateTime?>> expression, IDictionary<string, object> htmlAttributes)
        {
            var modelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
            DateTime? dt_value = null;
            if (modelMetadata != null && modelMetadata.ModelType == typeof(DateTime?) && modelMetadata.Model != null)
            {
                dt_value = Convert.ToDateTime(modelMetadata.Model);
            }
            return DatePickerHelper(htmlHelper, ExpressionHelper.GetExpressionText(expression), dt_value, htmlAttributes);
        }

        /// <summary>
        /// 生成日历选择控件。
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="name"></param>
        /// <param name="value">需绑定到控件的日期值。如果为null则不绑定input控件的value属性。</param>
        /// <param name="htmlAttributes"></param>
        /// <returns></returns>
        private static MvcHtmlString DatePickerHelper(HtmlHelper htmlHelper, string name, DateTime? value, IDictionary<string, object> htmlAttributes)
        {
            name = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }

            TagBuilder tagBuilder = new TagBuilder("input");
            tagBuilder.MergeAttributes(htmlAttributes);
            tagBuilder.MergeAttribute("type", "text");
            tagBuilder.MergeAttribute("name", name, true);

            string valueParameter = "";
            if (value.HasValue)
                valueParameter = value.Value.ToString("yyyy-MM-dd");

            //string attemptedValue = (string)GetModelStateValue(htmlHelper, name, typeof(string));
            tagBuilder.MergeAttribute("value", /*attemptedValue ??*/ valueParameter, true);
            tagBuilder.GenerateId(name);

            // If there are any errors for a named field, we add the css attribute.
            ModelState modelState;
            if (htmlHelper.ViewData.ModelState.TryGetValue(name, out modelState))
            {
                if (modelState.Errors.Count > 0)
                {
                    tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
                }
            }

            return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.SelfClosing));
        }

        //internal static object GetModelStateValue(HtmlHelper htmlHelper, string key, Type destinationType)
        //{
        //    ModelState modelState;
        //    if (htmlHelper.ViewData.ModelState.TryGetValue(key, out modelState))
        //    {
        //        if (modelState.Value != null)
        //        {
        //            return modelState.Value.ConvertTo(destinationType, null /* culture */);
        //        }
        //    }
        //    return null;
        //}
    }
}
